package top.hudk.multithreading.reorder;

import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 类描述：演示指令重排
 * @author HuDongkang
 * @date 2021/11/2
 */
public class ReOrder {


    private static ThreadPoolExecutor threadPoolExecutor = null;

    private static int x = 0;
    private static int y = 0;
    private static int a = 0;
    private static int b = 0;

    public static void main(String[] args) throws InterruptedException {
        executor();
        int o = 0;
        while (true) {
            if(o % 1000 == 0){
                System.out.print(o + "\r");
            }
            x = 0;
            y = 0;
            a = 0;
            b = 0;
            CountDownLatch latch = new CountDownLatch(2);

            o ++;
            threadPoolExecutor.execute(() -> {
                a = 1;
                x = b;
                latch.countDown();
            });

            threadPoolExecutor.execute(() -> {
                b = 1;
                y = a;
                latch.countDown();
            });

            latch.await();

            if(x == 0 && y == 0){
                System.out.println(o + "\nx = " + x + "\ny = " + y);
                break;
            }
        }
        threadPoolExecutor.shutdown();
        System.out.println("end");
    }

    /**
     * 自定义配置异步执行器
     * @return 执行器
     */
    private static void executor() {

        if(Objects.isNull(threadPoolExecutor)){
            threadPoolExecutor = new ThreadPoolExecutor(1000, 2000, 20, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(), new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r);
                }
            }, new ThreadPoolExecutor.CallerRunsPolicy());
        }

    }


}
